package com.bac.rentmap.web.controller.ad.image;

import java.io.IOException;
import java.util.logging.Logger;

import javax.jdo.JDOObjectNotFoundException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.datanucleus.exceptions.NucleusObjectNotFoundException;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

import com.bac.rentmap.ad.flat.image.FlatImage;
import com.bac.rentmap.ad.flat.image.FlatImageService;
import com.google.appengine.api.memcache.MemcacheService;

public class ServeImageController extends MultiActionController {
    private static final Logger log = Logger
            .getLogger(ServeImageController.class.getName());

    private FlatImageService flatImageService;
    private MemcacheService cache;

    public ModelAndView thumbnail(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        String flatImageId = request.getParameter("flatImageId");
        byte[] res = (byte[]) cache.get(flatImageId);
        if (res == null) {
            FlatImage flatImage = getFlatImage(request);
            if(flatImage != null){
                res = flatImage.getThumbnail().getBytes();
            }
            else{
                log.warning("Can't find image: " + flatImageId);
            }
            if(res != null)
                cache.put(flatImageId, res);
        }
        if (res != null) {
            writeImage(res, response);
        }
        return null;
    }

    public ModelAndView image(HttpServletRequest request,
            HttpServletResponse response) throws Exception {
        String userAgent = request.getHeader("User-Agent");
        String referer = request.getHeader("Referer");
        log.fine("User-Agent: " + userAgent);
        log.fine("Referer: " + referer);
        if(userAgent != null && userAgent.contains("CPython")){
            log.info("Blocking " + request.getRemoteHost() + " - " + request.getRemoteAddr());
            response.setContentType("text");
            response.getWriter().write("Do not crawl images more often than once in 2 hours. It puts the server down! Images are readonly. Do not crawl the same image for the same URL twice!");
            return null;
        }
        FlatImage flatImage = getFlatImage(request);
        if (flatImage != null) {
            writeImage(flatImage.getImage().getBytes(), response);
        }
        return null;
    }

    private void writeImage(byte[] bytes, HttpServletResponse response)
            throws IOException {
        response.setContentType("image/jpeg");
        response.getOutputStream().write(bytes);
    }

    private FlatImage getFlatImage(HttpServletRequest request) {
        String flatImageId = request.getParameter("flatImageId");
        log.fine("Serving image for flatImageId: " + flatImageId);
        try{
            return flatImageService.getFlatImage(Long.valueOf(flatImageId));
        }
        catch(NucleusObjectNotFoundException e){
            return null;
        }
        catch(JDOObjectNotFoundException e){
          return null;
        }
    }

    @Override
	protected ModelAndView handleRequestInternal(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
    	response.addHeader("Cache-Control", "public");
		return super.handleRequestInternal(request, response);
	}

	@Required
    public void setFlatImageService(FlatImageService flatImageService) {
        this.flatImageService = flatImageService;
    }

    @Required
    public void setCache(MemcacheService cache) {
        this.cache = cache;
    }
}
